import { URL, Toast, ajax, engine, computeScore } from '../../utils/index'
import error from '../../utils/error'
let wsEngine = engine.createWsEngine({});
var recorder = wx.getRecorderManager()
const options = {
  duration: 300000, //指定录音的时长，单位 ms
  sampleRate: 16000, //采样率
  numberOfChannels: 1, //录音通道数
  encodeBitRate: 96000, //编码码率
  format: 'mp3', //音频格式，有效值 aac/mp3
  frameSize: 50, //指定帧大小，单位 KB
}

Component({
  properties: {
    entity: {
      type: Object,
      value: ''
    },
    status: {
      type: Boolean,
      value: false
    },
    content: {
      type: String,
      value: ''
    },
    src: {
      type: String,
      value: ''
    },
    lastNext: {
      type: Boolean,
      value: true
    },
    default: {
      type: Boolean,
      value: true
    }
  },
  data: {
    keys: null,
    result: null,
    loading: false,
    timer: null,
    startTime: null,
    start_end: true // true 是开始 false 结束
  },
  /**
   * 函数
   */
  methods: {
    lastClick() {
      this.triggerEvent("last")
    },
    nextClick() {
      this.triggerEvent("next")
    },
    //长按开始事件
    // handleTouchStart: function (e) {
    //   this.setData({
    //     startTime: e.timeStamp / 1000
    //   })
    //   console.log("开始事件: startTime = " + e.timeStamp / 1000);
    // },
    //长按离开事件
    // handleTouchEnd: function (e) {
    //   let {startTime} = this.data
    //   this.setData({
    //     endTime: e.timeStamp / 1000 - startTime
    //   })
    //   recorder.stop()
    // },
    handleClick() {
      this.triggerEvent("cancel")
      this.data.start_end ? (this.handleLongPress(), this.timing()) : recorder.stop()
    },
    // 定时器
    timing() {
      let { timer } = this.data
      timer = setInterval(() => {
        this.setData({
          startTime: this.data.startTime += 1
        })
      }, 1000)
      this.setData({
        timer: timer
      })
    },
    handleLongPress() {
      console.log('===========校验录音权限==========');
      wx.getSetting({
        success: (res) => {
          if (!res.authSetting['scope.record']) {
            //调取小程序新版授权页面
            wx.authorize({
              scope: 'scope.record',
              success: () => (this.wsEngineOnChange(), this.startAI(), recorder.start(options)),
              fail: () => (console.log("微信录音授权失败"), this.authorizationShowModal())
            })
          } else (this.wsEngineOnChange(), this.startAI(), recorder.start(options))
        }
      })
    },
    // 拒绝授权或授权失败提示框
    authorizationShowModal() {
      wx.showModal({
        title: '提示',
        content: '您未授权录音，功能将无法使用',
        showCancel: true,
        confirmText: "授权",
        confirmColor: "#52a2d8",
        success: (res) => (res.confirm ? this.settdingPage() : '')
      })
    },
    // 跳转授权设置页面
    settdingPage() {
      wx.openSetting({
        success: (res) => {
          res.authSetting['scope.record'] ? console.log('授权成功') : console.log('授权设置失败')
        }, fail: () => console.log("授权设置页面录音失败")
      })
    },
    // 启动AI
    startAI() {
      return new Promise((resolve, reject) => {
        wsEngine.start({
          audio: {
            duration: 300000,//传入参数手动设置录音时长
            sampleRate: 16000,
            audioType: "mp3",
            channel: 1,
            sampleBytes: 2
          },
          request: {
            coreType: "cn.pred.raw",
            refText: this.data.content,
            attachAudioUrl: 1,
            rank: 100,
          },
          app: this.data.keys,
          success: (res) => {
            this.setData({
              tokenId: res.tokenId ? res.tokenId : ''
            }), console.log("===启动AI======success=============  " + JSON.stringify(res)), resolve(res)
          }, fail: (res) => (console.log("===启动AI======fail=============  " + JSON.stringify(res)), reject(res))
        })
      })
    },
    // 获取AI密钥授权
    getSign() {
      return new Promise((resolve, reject) => {
        ajax.get('/applet/sign/getSign').then(res => {
          if (res.data.code === 1) {
            this.setData({
              keys: res.data.data
            }), resolve(res)
          } else (ajax.toast.fail('获取AI密钥失败\n请联系管理员'), reject(res), console.log(res))
        }).catch(e => (ajax.toast.fail('获取AI密钥请求失败,请联系管理员'), reject(e), console.log(e)))
      })
    },
    // 发送AI录音
    sendData(frameBuffer) {
      wsEngine.feed({
        data: frameBuffer,    // frameBuffer为微信录音机回调的音频数据
        success: (res) => console.log('发送AI录音函数success================', res),
        fail: (res) => console.log('发送AI录音函数fail===================', res)
      })
    },
    // 结束AI发送录音------
    finishSendData() {
      console.log('结束AI发送录音')
      this.setData({
        loading: !this.data.loading
      })
      wsEngine.stop();
    },

    // AI 事件监听函数
    wsEngineOnChange() {
      wsEngine.onResult((res) => {
        console.log("===收到评分结果=============JSON" + JSON.stringify(res), res);
        if (res.result.error && res.result.error.errID) return Toast(error[res.result.error.errID])
        let [score, result, audioUrl] = [computeScore(res.result), res.result, 'http://' + res.audioUrl + '.mp3'];
        console.log("===发送计算结果=============", { score, result, audioUrl });
        this.triggerEvent("change", { score, result, audioUrl })
        this.setData({
          loading: !this.data.loading
        })
      });
      wsEngine.onErrorResult((res) => {
        console.log("===收到错误结果=============" + JSON.stringify(res))
      });
    },
    // 小程序录音事件监听函数
    recorderOnChange() {
      // 监听录音开始事件
      recorder.onStart(res => {
        this.setData({
          start_end: false
        })
        console.log('录音开始事件==================', res)
      })
      // 监听录音继续事件
      recorder.onResume(res => {
        console.log('录音继续事件==================', res)
      })
      // 监听录音暂停事件
      recorder.onPause(res => {
        console.log('录音暂停事件==================', res)
      })
      // 监听录音结束事件
      recorder.onStop(res => {
        let { startTime, timer } = this.data, time = startTime
        console.log('录音结束事件==================时间=' + time)
        clearInterval(timer)
        this.setData({
          start_end: !this.data.start_end,
          timer: null,
          startTime: null,
        })
        time > 5 ? this.finishSendData() : (Toast('录音时间过短'), wsEngine.reset());
      })
      // 监听已录制完指定帧大小的文件事件。如果设置了 frameSize，则会回调此事件。
      recorder.onFrameRecorded(res => {
        this.sendData(res.frameBuffer)
        console.log('发送AI录音片段==================', res)
      })

      // 监听录音错误事件
      recorder.onError(res => {
        // Toast.fail('录音错误')
        console.log('监听录音错误事件==================', res)
      })
    },
  },
  // 属性监听
  observers: {},
  // 组件生命周期函数，在组件实例进入页面节点树时执行，注意此时不能调用setData
  created: function () { },
  // 组件生命周期函数，在组件实例进入页面节点树时执行。
  attached: function () { },
  // 在组件布局完成后执行，此时可以获取节点信息
  ready: function () {
    Toast.setDefaultOptions({
      duration: 3000
    })
    this.recorderOnChange(), this.getSign()
  },
  // 在组件实例被移动到节点树另一个位置时执行
  moved: function () { },
  // 在组件实例被从页面节点树移除时执行
  detached: function () { }
});